package com.michaelbulava.TFS.vc.tfsitem;

import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.michaelbulava.TFS.common.item.ServerItemPath;
import com.michaelbulava.TFS.tasks.vc.QueryItemsExtendedTask;
import com.microsoft.tfs.core.clients.versioncontrol.GetItemsOptions;
import com.microsoft.tfs.core.clients.versioncontrol.path.ServerPath;
import com.microsoft.tfs.core.clients.versioncontrol.soapextensions.*;
import com.microsoft.tfs.util.Check;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * Created by MichaelA on 7/22/2015.
 */
public class TFSItemFactory {

//    public static TFSItem getItem(ExtendedItem extendedItem)
//    {
//        return getItem(extendedItem, null);
//    }

    public static TFSItem getItem(ExtendedItem extendedItem, Workspace workspace){//, Project project) {
        if (extendedItem.getItemType() == ItemType.FILE) {
            return new TFSFile(extendedItem, workspace);//, project);
        }
        if (extendedItem.getItemType() == ItemType.FOLDER) {
            return new TFSFolder(extendedItem, workspace);//, project);
        }
        return new TFSItem(extendedItem, workspace);//, project);
    }

//    public static TFSItem createWithChildren(ExtendedItem[] items) {
//        return createWithChildren(items, false);
//    }

//    public static TFSItem createWithChildren(ExtendedItem[] items, boolean isPartialTree) {
//        TFSFolder root = (TFSFolder)getItem(items[0]);
//        if (!isPartialTree)
//            root.setChildrenEmpty();
//
//        createWithChildren(root, items, 1, isPartialTree);
//        return root;
//    }

    public static TFSItem createImplicitWithChildren(ExtendedItem[] extendedItems, boolean b, Workspace workspace){
                                                     //Project project) {
        if ((extendedItems == null) || (extendedItems.length == 0)) {
            return null;
        }
        ServerItemPath implicitPath = new ServerItemPath(extendedItems[0].getTargetServerItem()).getParent();
        TFSFolder root = new TFSFolder(implicitPath, workspace);//, project);
        for (int i = 0; i < extendedItems.length; i++) {
            root.addChild(getItem(extendedItems[i],workspace));//, project));
        }
        TFSItem[] implicitChildren = getImplicitAdds(root);
        for (int i = 0; i < implicitChildren.length; i++) {
            root.addChild(implicitChildren[i]);
        }
        return root;
    }

    private static int createWithChildren(TFSFolder root, ExtendedItem[] items, int startIndex, boolean isPartialTree)
    {
        int currentIndex = startIndex;
        Check.notNull(root, "root");
        Check.notNull(root.getFullPath(), "root.getFullPath()");
        while (currentIndex < items.length)
        {
            ExtendedItem current = items[currentIndex];
            String parentOfCurrent = ServerPath.getParent(current.getTargetServerItem());
            if (ServerPath.isDirectChild(root.getFullPath(), current.getTargetServerItem()))
            {
                TFSItem directChild = getItem(current, root.getWorkspace());//, root.getProject());
                if ((directChild instanceof TFSFolder)) {
                    if (!isPartialTree) {
                        ((TFSFolder)directChild).setChildrenEmpty();
                    }
                }
                root.addChild(directChild);

                currentIndex++;
            }
            else if (ServerPath.isChild(root.getFullPath(), current.getTargetServerItem()))
            {
                TFSFolder childParent = (TFSFolder)root.getChildByFullPath(parentOfCurrent);
                currentIndex = createWithChildren(childParent, items, currentIndex, isPartialTree);
            }
            else
            {
                return currentIndex;
            }
        }
        TFSItem[] implicitChildren = getImplicitAdds(root);
        for (int i = 0; i < implicitChildren.length; i++) {
            root.addChild(implicitChildren[i]);
        }
        return items.length;
    }

    private static String getParentPath(ExtendedItem current) {
        String path = current.getTargetServerItem();
        int lastSlash = path.lastIndexOf('/');
        String parentPath = path.substring(0, lastSlash);
        return "$".equals(parentPath) ? "$/" : parentPath;
    }

    public static TFSItem getItemAtPath(Workspace workspace, Project project, String path)
    {
        QueryItemsExtendedTask queryTask = new QueryItemsExtendedTask(project, workspace, path, ItemType.ANY,
                DeletedState.NON_DELETED, RecursionType.NONE, GetItemsOptions.INCLUDE_BRANCH_INFO);

        ProgressManager.getInstance().run(queryTask);
        if (queryTask.isOk())
            return null;

        ExtendedItem[][] extendedItems = queryTask.getItems();
        if ((extendedItems.length != 1) || (extendedItems[0].length != 1)) {
            return null;
        }
        return getItem(extendedItems[0][0], workspace);//, project);
    }

//    public static TFSFolder createRootWithChildren(ExtendedItem[] items, boolean isPartialTree) {
//        if (items.length == 0)
//            return getRoot();
//        if (new ServerItemPath(items[0].getTargetServerItem()).isRoot())
//            return (TFSFolder)createWithChildren(items, isPartialTree);
//
//        TFSFolder root = getRoot();
//        createWithChildren(root, items, 0, isPartialTree);
//        return root;
//    }

    public static TFSFolder getRoot(Workspace workspace){//, Project project) {
        return new TFSFolder(ServerItemPath.ROOT, workspace);//, project);
    }

//    public static TFSFolder getRoot() {
//        return new TFSFolder(ServerItemPath.ROOT);
//    }

    public static TFSItem[] getImplicitAdds(TFSFolder parent) {

        Set implicitAddPathSet = new HashSet();
        List implicitAddList = new ArrayList();

        //TODO come back to this
//        PendingChange[] pendingChanges = repository.getPendingChangeCache().getPendingChangesByServerPathRecursive(parent.getFullPath());
//        for (int i = 0; i < pendingChanges.length; i++)
//        {
//            String relative = ServerPath.makeRelative(pendingChanges[i].getServerItem(), parent.getFullPath());
//
//            int firstSlash = relative.indexOf("/");
//
//            boolean isParentFolder = false;
//            if (firstSlash >= 0)
//            {
//                relative = relative.substring(0, firstSlash);
//                isParentFolder = true;
//            }
//            if (relative.length() > 0)
//            {
//                String childPath = ServerPath.combine(parent.getFullPath(), relative);
//                if ((parent.getChildByFullPath(childPath) == null) && (!implicitAddPathSet.contains(childPath)))
//                {
//                    if (isParentFolder) {
//                        implicitAddList.add(new TFSFolder(new ServerItemPath(childPath), parent.getWorkspace(),
//                                parent.getProject()));
//                    }
//                    implicitAddPathSet.add(childPath);
//                }
//            }
//        }
        return (TFSItem[])implicitAddList.toArray(new TFSItem[implicitAddList.size()]);
    }
}
